<template>
    <view>
        <z-paging ref="pagingRef" v-model="messages" @query="queryList" use-chat-record-mode>
            <template #top>
                <MrCustom bg-color="bg-gradual-blue " is-back>
                    <template #backText>
                        返回
                    </template>
                    <template #content>
                        <view v-if="loading">
                            <text class="cuIcon-loading icon-rotate">
                            </text>
                            响应中...
                        </view>
                    </template>
                </MrCustom>
            </template>
            <div class="chat">
                <div class="chat-messages">
                    <div v-for="(message, index) in messages" :key="index"
                         :class="['message', message.role === 'user' ? 'message-sent' : 'message-received']">
                        <div v-if="message.role==='user'" class="message-sender message-sent">
                            <MrAvatar :src="userStore.userInfo.avatar" :size="90"></MrAvatar>
                        </div>
                        <div v-else class="message-sender message-received">
                            <MrAvatar src="/upload/images/2023-05-28/m6m3dxeiyf.jpg" :size="90"></MrAvatar>
                        </div>
                        <div class="message-bubble text-break-all"
                             :class="message.role === 'user' ? 'sent' : 'received'">
                            {{ message.content }}
                        </div>
                    </div>
                </div>
            </div>
            <template #bottom>
                <view class="bg-grey flex justify-center padding-tb-xs" style="opacity: 60%">
                    <button class="cu-btn round"
                            style="width: 30%"
                            @click="clickPrompt(item)"
                            :key="index"
                            v-for="(item,index) in prompts">
                        <text class="text-cut">{{ item }}</text>
                    </button>
                </view>
                <view class="chat-input-bar">
                    <view class="chat-input-container">
                        <input class="chat-input" v-model="newMessage"
                               maxlength="-1" type="text" placeholder="请输入内容" @confirm="sendMessage">
                    </view>
                    <view class="chat-input-send" @click="sendMessage">
                        <text class="chat-input-send-text">发送</text>
                    </view>
                </view>
            </template>
        </z-paging>
    </view>
</template>

<script setup lang="ts">

import MrCustom from "@/components/common/MrCustom.vue";
import {nextTick, onMounted, ref} from "vue";
import MrAvatar from "@/components/common/MrAvatar.vue";
import {useUserStore} from "@/store";

const pagingRef = ref()
const userStore = useUserStore()
const newMessage = ref('')
const prompts = ref<string[]>([])
const prefixMessage = ref([
    {
        role: 'system',
        content: '先给你介绍一下系统：“PICC智慧管家，它是PICC信息管理平台简化模型，建立PICC信息管理平台，实现互联网+医疗。' +
            'PICC信息管理平台中心（电脑端）和手机客户端（微信小程序或APP）组成，手机客户端包括医护端和患者端，平台可采集PICC置管，维护，拔管全过程数据和图像，以及过程中产生的咨询，会诊，随访等数据 ，实现PICC的数据统计及分析。”。' +
            '你的任务是当这个系统的AI管家，负责用一句话(50个字以内)回答用户问题。我的第一句是：“你好”'
    },
])
const messages = ref([])
const loading = ref(false)
onMounted(() => {
    prompts.value = startPrompt()
})
const clickPrompt = (str: string) => {
    if (loading.value) {
        uni.showToast({
            icon: 'error',
            title: '正在响应...'
        })
        return
    }
    newMessage.value = str
    sendMessage()
}

const sendMessage = () => {
    if (loading.value) {
        uni.showToast({
            icon: 'error',
            title: '正在响应...'
        })
        return
    }
    console.log(newMessage.value)
    if (newMessage.value.trim() !== '') {
        pagingRef.value.addChatRecordData({
            role: 'user',
            content: newMessage.value,
        });
        newMessage.value = ''
        nextTick(() => {
            getResponse()
        })

    } else {
        uni.showToast({
            icon: 'error',
            title: '不能发送空消息',
        })
    }
}

function typewriterEffect(str: any, speed: any) {
    let i = 0;
    const timer = setInterval(() => {
        let message = messages.value.at(messages.value.length - 1);
        message.content += str.charAt(i);
        i++;
        if (i > str.length) {
            clearInterval(timer);
        }
    }, speed);
}

const getResponse = async () => {
    try {
        const url = 'https://zzjtpp.top/ChatGPT';
        let takeMessage = JSON.parse(JSON.stringify(messages.value.slice(-5)))
        takeMessage[takeMessage.length - 1].content =
            takeMessage[takeMessage.length - 1].content + '。回答内容占一行。回答后总结出三个可能相关的问题，每条问题占一行开头用“|”符号'
        const data = {
            "messages": [
                ...prefixMessage.value,
                ...takeMessage,
            ],
            "stream": true,
            "model": "gpt-3.5-turbo",
            "temperature": 1,
            "presence_penalty": 0
        };

        loading.value = true;
        const response = await uni.request({
            url: url,
            method: 'POST',
            header: {
                'content-type': 'application/json;charset=UTF-8',
                'Authorization': 'Bearer ak-zzj314314',

            },
            responseType: 'arraybuffer',
            data: JSON.stringify(data),
            success: (res) => {
                let str = buf2str(res.data)
                if (str.includes("Rate limit")) {
                    uni.showToast({
                        icon: 'error',
                        title: '请不要太着急',
                    })
                    messages.value.pop()
                    return
                }
                pagingRef.value.addChatRecordData({
                    role: 'assistant',
                    content: '',
                });

                console.log(str)
                let strs = str.split('|')
                typewriterEffect(strs[0], 20)
                prompts.value = strs.slice(1)
            },
            complete: (res) => {
                loading.value = false;
            }
        })

        // const requestTask = uni.request({
        //     url: url,
        //     method: 'POST',
        //     header: {
        //         'Content-Type': 'application/json; charset=utf-8',
        //         'Authorization': 'Bearer ak-zzj314314',
        //     },
        //     responseType: 'arraybuffer',
        //     enableChunked: true,
        //     data: JSON.stringify(data),
        //     success: function (res) {
        //         console.log(res)
        //     }
        // })
        //
        //
        // requestTask.onHeadersReceived(function (res) {
        //     console.log(res)
        //     pagingRef.value.addChatRecordData({
        //         role: 'assistant',
        //         content: '',
        //     });
        // })


        // requestTask.onChunkReceived(function (response) {
        //
        //     const arrayBuffer = response.data;
        //     let text = buf2str(arrayBuffer)
        //     let message = messages.value.at(messages.value.length - 1);
        //     console.log(arrayBuffer,new Int8Array(arrayBuffer),text)
        //     message.content += text;
        //     console.log(message)
        // })

        // const textDecoder = new TextDecoder();
        // let value = new ArrayBuffer(0); // 初始化一个空的 ArrayBuffer
        // requestTask.onChunkReceived(function (response) {
        //     const chunk = response.data;
        //     value = concatenateArrayBuffers(value, chunk); // 将新的 chunk 追加到 value 中
        //     while (value.byteLength >= 3) {
        //         const slice = value.slice(0, 3); // 获取长度为3的子数组进行解码
        //         // const str = textDecoder.decode(new Uint8Array(slice));
        //         const str = arrayBuffer2String(slice)
        //         let message = messages.value.at(messages.value.length - 1);
        //         message.content += str;
        //         console.log(slice, str);
        //         value = value.slice(3); // 删除已使用的部分
        //     }
        // });
        // console.log(total,textDecoder.decode(total))

    } catch (error) {
        console.error(error);
        // 处理错误
    }
}

function buf2str(buffer: any) {
    let encodedString = String.fromCodePoint.apply(null, new Uint8Array(buffer));
    let decodedString = decodeURIComponent(escape(encodedString));//没有这一步中文会乱码
    return decodedString
}

const queryList = (pageNo: any, pageSize: any) => {
    let str = startMessage()
    pagingRef.value.addChatRecordData({
        role: 'assistant',
        content: '',
    });
    typewriterEffect(str, 30)
}

const startMessage = () => {
    const list = [
        '您好，我是PICC智慧管家，很高兴为您服务。请问有什么关于PICC的问题可以帮您解答？',
        '您好！我是PICC智慧管家，有什么需要帮助的吗？关于PICC的任何问题，我都可以为您解答。',
        '您好，欢迎使用PICC智慧管家。请问您有什么关于PICC的问题需要我帮助解答吗？',
        '你好，请问有什么关于PICC的问题需要我来回答或者帮助你解决吗？',
        '您好，我是PICC智慧管家，欢迎您咨询关于PICC的问题。请问有什么需要我帮助的吗？']
    const index = Math.floor(Math.random() * list.length);
    return list[index];
}
const startPrompt = () => {
    const list = [
        '什么是PICC管道，为什么在医疗中使用它？',
        '如何减轻PICC置管时的疼痛感？',
        'PICC置管后有哪些注意事项？',
        'PICC置管后可能会出现哪些问题，如何处理？',
        '如何进行PICC管道的护理，有哪些注意事项？',
        '如何正确地更换PICC管道？',
        '如何进行PICC管道的拔除，有哪些注意事项？',
        '中心静脉置管有哪些优劣势？？',
        'PICC置管过程中需要注意哪些安全问题',
        '如何选择一家专业的医疗机构进行PICC置管？',
        '是否每次PICC置管都会很疼痛？',
        '中心静脉置管能否在家庭环境下进行？',
    ]
    const selectedPrompts: string[] = [];
    while (selectedPrompts.length < 3) {
        const randomIndex = Math.floor(Math.random() * list.length);
        const prompt = list[randomIndex];
        if (!selectedPrompts.includes(prompt)) {
            selectedPrompts.push(prompt);
        }
    }
    return selectedPrompts;
}
</script>

<style scoped>
.chat {
    display: flex;
    flex-direction: column;
}

.chat-messages {
    flex-grow: 1;
    overflow-y: auto;
    padding: 10px;
}

.message {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    margin-bottom: 10px;
}

.message-sent {
    justify-content: flex-end;
}

.message-received {
    justify-content: flex-start;
}

.message-bubble {
    display: inline-block;
    padding: 10px;
    max-width: 80%;
    border-radius: 15px;
    margin-bottom: 5px;
    color: white;
    font-weight: bold;
}

.sent {
    background-color: #4caf50;
    align-self: flex-end;
}

.received {
    background-color: #2196f3;
    align-self: flex-start;
}

.message-sender {
    display: flex;
    font-size: 12px;
    color: #666;
    margin-bottom: 5px;
}


.chat-input-bar {
    display: flex;
    flex-direction: row;
    align-items: center;
    background-color: #f8f8f8;
    padding: 0px 10px;
}

.chat-input-container {
    flex: 1;
    display: flex;
    padding: 10px;
    background-color: white;
    border-radius: 10px;
}

.chat-input {
    flex: 1;
    font-size: 15px;
}

.chat-input-send {
    background-color: #007AFF;
    margin: 5px 5px 10px 10px;
    border-radius: 10px;
    padding: 8px 20px;

}

.chat-input-send-text {
    color: white;
    font-size: 16px;
}

.icon-rotate {
    display: inline-block;
    animation: rotate 2s linear infinite;
}

@keyframes rotate {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(360deg);
    }
}

</style>